import * as THREE from 'three'
import createApp from '../../core'

function createLatheGeometry (dom: HTMLElement) {
  const { camera, scene, update, gui } = createApp(dom)
  camera.position.set(0, 0, 100)
  camera.lookAt(scene.position)

  const mesh = createLatheFromGeometry()
  mesh.position.set(-50, 0, 0)
  scene.add(mesh)

  const bufferMesh = createLatheFromBufferGeometry()
  bufferMesh.position.set(50, 0, 0)
  scene.add(bufferMesh)

  update((time: number) => {
    const angle = time / 1000
    mesh.rotation.set(angle, angle, 0)

    bufferMesh.rotation.set(angle, angle, 0)
  })

  function updateMeshs () {
    generateGeometry(mesh)
    generateGeometry(bufferMesh)
  }

  gui.add(data, 'segments', 1, 30, 1).onChange(updateMeshs)
  gui.add(data, 'phiStart', 1, Math.PI * 2).onChange(updateMeshs)
  gui.add(data, 'phiLength', 1, Math.PI * 2).onChange(updateMeshs)
}

const data = {
  segments: 12,
  phiStart: 0,
  phiLength: Math.PI * 2
}

function createPath () {
  const points = [
    new THREE.Vector2(30, 0),
    new THREE.Vector2(20, 15),
    new THREE.Vector2(25, 15),
    new THREE.Vector2(10, 30),
    new THREE.Vector2(15, 30),
    new THREE.Vector2(0, 45)
  ]
  return points
}

function createLatheFromGeometry () {
  const { segments, phiStart, phiLength } = data
  const path = createPath()
  const geometry = new THREE.LatheGeometry(path, segments, phiStart, phiLength)
  const material = new THREE.MeshBasicMaterial({ color: 0xffff00, wireframe: true })
  const lathe = new THREE.Mesh(geometry, material)
  return lathe
}

function createLatheFromBufferGeometry () {
  const { segments, phiStart, phiLength } = data
  const path = createPath()
  const geometry = new THREE.LatheBufferGeometry(path, segments, phiStart, phiLength)
  const material = new THREE.MeshNormalMaterial({ side: THREE.DoubleSide })
  const lathe = new THREE.Mesh(geometry, material)
  return lathe
}

function generateGeometry (mesh: THREE.Mesh) {
  const { segments, phiStart, phiLength } = data
  const path = createPath()
  const geometry = new THREE.LatheBufferGeometry(path, segments, phiStart, phiLength)
  mesh.geometry.dispose()
  mesh.geometry = geometry
}

export {
  createLatheGeometry
}
